<script setup lang="ts">
/**
 * 一个通用的表单页面,包含表格
 */
import {FormInstance} from "element-plus";
import {Ref} from "vue";
import {useGetOptions} from "@/utils/use/use-get-options";
import {DisplayTable} from "@/components/MyComponent/DisplayTable/displayInterface";
import {initPageQuery} from "@/utils/common-fn";

defineSlots<{
  operation(props: { row: Record<string, any> }): any
}>()
// table和编辑的时候有id  add的时候没有id
const props = defineProps<{
  options: DisplayTable,
}>()
const {api, attrs, initQuery, title} = props.options
const searchRef = ref<FormInstance>()

/**
 * 处理默认值
 */
// 默认attrs
const computedAttrs = computed(() => {
      let index = 0;
      return attrs.map((attr) => {
        let newAttr = {...attr, index: -1}
        const {formType, columnWidth, sort, query, code} = attr
        newAttr.formType = formType ?? 'input'
        newAttr.columnWidth = columnWidth ?? 120
        newAttr.sort = sort ?? true
        newAttr.query = query ?? true
        // 这个index是为了保证拿到的selectOptions能正确的得到index
        if (code) {
          newAttr.index = index++
        }
        return newAttr
      })
    }
)

/**
 * 处理options的问题
 */
const codes = computedAttrs.value.filter(item => item.code)
    .map(item => item.code) as string[]
let selectOptions = useGetOptions(...codes)


type Obj = Record<string, any>
/**
 * 表单公共字段
 */
const tableData: Ref<Obj[]> = ref([])
const total = ref(0)
const queryData = ref(initPageQuery(initQuery))

// 获取列表
async function getList() {
  [tableData.value, total.value] = await api.getList(queryData.value)
}

// 在getList的基础上初始化options数据
function getListPlus() {
  selectOptions = useGetOptions(...codes)
  getList()
}


// 排序
async function sortTable({prop, order}: {
  column: any,
  prop: string,
  order: 'descending' | 'ascending' | null
}) {
  if (order === 'descending' || !order) {
    queryData.value.order = {[prop]: 'desc'}
  } else {
    queryData.value.order = {[prop]: 'asc'}
  }
  getListPlus()
}


// 重置搜索
async function resetSearch(formEl: FormInstance | undefined) {
  if (!formEl) {
    return;
  }
  formEl.resetFields()
  queryData.value = initPageQuery(initQuery)
  await nextTick()
  getListPlus()
}

// 分页变化,查询
watch([() => queryData.value.pageSize, () => queryData.value.currentPage], () => {
  getListPlus()
})
// 载入查询
onMounted(async () => {
  await getList()
  // 处理options问题
})
</script>
<template>
  <x-card shadow="never" class="my-card">
    <!--  查询 -->
    <div><span class="text-lg m-b-2">{{ title }}</span></div>
    <el-form :inline="true" :model="queryData.query" ref="searchRef" label-suffix=":">
      <template v-for="item in computedAttrs">
        <el-form-item
            v-if="item.query"
            :label="item.label"
            :key="item.prop"
            :prop="item.prop"
        >
          <el-input v-if="['input'].includes(item.formType!)" v-model="queryData.query[item.prop]" clearable/>
          <el-input v-if="['textarea'].includes(item.formType!)" v-model="queryData.query[item.prop]"
                    type="textarea" autosize clearable/>
          <el-input-number v-if="item.formType === 'number'" v-model="queryData.query[item.prop]"/>
          <x-dict-select v-if="['select','radio'].includes(item.formType!)" v-model="queryData.query[item.prop]"
                         :type-code="item.code!" type="select"/>
        </el-form-item>
      </template>
      <el-form-item>
        <el-button type="primary" @click="getListPlus()">查询</el-button>
        <el-button @click="resetSearch(searchRef)" circle>
          <i-ep-refresh-left/>
        </el-button>
      </el-form-item>
    </el-form>
    <!-- 表格 -->
    <el-table :data="tableData" style="width: 100%" show-overflow-tooltip @sort-change="sortTable">
      <template v-for="item in computedAttrs">
        <el-table-column
            v-if="['input','number'].includes(item.formType!)"
            :prop="item.prop" :label="item.label" :min-width="item.columnWidth!"
            :sortable="item.sort? 'custom': false" align="center"/>
        <el-table-column
            v-if="['textarea'].includes(item.formType!)"
            :prop="item.prop" :label="item.label" :min-width="item.columnWidth!"
            :sortable="item.sort? 'custom': false">
          <template #default="{row}">
            <el-input type="textarea" readonly autosize :model-value="row[item.prop]"/>
          </template>
        </el-table-column>
        <el-table-column
            v-if="['select','radio'].includes(item.formType!)"
            :prop="item.prop"
            :key="item.prop"
            :label="item.label"
            :min-width="item.columnWidth!"
            :sortable="item.sort!"
            align="center"
        >
          <template #default="{row}">
            <x-tag :value="row[item.prop]" :options="selectOptions[item.index]"/>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <!--  分页-->
    <XPagination
        v-model:page-size="queryData.pageSize"
        v-model:current-page="queryData.currentPage"
        v-model:total="total"
    />
  </x-card>
</template>
<style scoped lang="scss">
.el-card__body > * + * {
  margin-top: 1em;
}
</style>